package com.dirox.plugins.jira.servlet;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.atlassian.jira.bc.issue.search.SearchService;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.search.SearchException;
import com.atlassian.jira.jql.builder.JqlClauseBuilder;
import com.atlassian.jira.jql.builder.JqlQueryBuilder;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.project.ProjectManager;
import com.atlassian.jira.security.JiraAuthenticationContext;
import com.atlassian.jira.user.util.UserManager;
import com.atlassian.jira.web.bean.PagerFilter;
import com.dirox.plugins.ao.entities.Note;
import com.dirox.plugins.ao.service.NoteService;
import com.dirox.plugins.ao.service.NoteServiceImpl;

//import com.atlassian.sal.api.user.UserManager;

public class ProcessServlet extends HttpServlet {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private final JiraAuthenticationContext context;
	private NoteService noteService;
	private UserManager jiraUserManager;
	private SearchService searchService;
	private ProjectManager projectManager;

	public ProcessServlet(JiraAuthenticationContext context,
			NoteService noteService, UserManager jiraUserManager,
			SearchService searchService, ProjectManager projectManager) {
		this.context = context;
		this.noteService = checkNotNull(noteService);
		this.jiraUserManager = checkNotNull(jiraUserManager);
		this.searchService = checkNotNull(searchService);
		this.projectManager = checkNotNull(projectManager);
	}

	public List<Issue> getIssues(String projectName) {
		final com.atlassian.crowd.embedded.api.User currentUser = context
				.getLoggedInUser();
		JqlClauseBuilder jqlClauseBuilder = JqlQueryBuilder.newClauseBuilder();
		com.atlassian.query.Query query = jqlClauseBuilder.project(projectName)
				.buildQuery();
		com.atlassian.jira.issue.search.SearchResults searchResults = null;
		try {
			searchResults = searchService.search(currentUser, query,
					PagerFilter.getUnlimitedFilter());
		} catch (SearchException e) {
			e.printStackTrace();
		}
		return searchResults.getIssues();
	}

	public List<Issue> getIssues() {
		List<Issue> issues = new ArrayList<Issue>();
		List<Project> projects = projectManager.getProjectObjects();
		for (Project p : projects) {
			issues.addAll(getIssues(p.getName()));
		}
		return issues;
	}

	public Issue getIssue(String key) {
		for (Issue i : getIssues()) {
			if (i.getKey().equals(key)) {
				return i;
			}
		}
		return null;
	}

	@Override
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		enforceLoggedIn(request, response);
		response.setContentType("text/html;charset=UTF-8");

		response.setCharacterEncoding("UTF-8");
		request.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		if (request.getParameter("action") != null) {
			String action = request.getParameter("action");
			com.atlassian.crowd.embedded.api.User currentUser = context
					.getLoggedInUser();

			if (action.equals("Create")) {
				if (request.getParameter("content") != null
						&& request.getParameter("content").equals("") == false) {
					String content = request.getParameter("content");
					String priority = request.getParameter("priority");
					Note note = noteService.add(content,
							Integer.parseInt(priority));
					if (request.getParameter("noteid") == null
							|| request.getParameter("noteid").length() == 0) {
						if (request.getParameter("user") != null
								&& request.getParameter("user").equals("-1") == false) {
							String userName = request.getParameter("user");
							com.atlassian.crowd.embedded.api.User user = jiraUserManager
									.getUser(userName);
							noteService.tagNoteToUser(note, user);
						}
					} else {
						int noteid = Integer.parseInt(request
								.getParameter("noteid"));
						String userName = context.getLoggedInUser().getName();
						// noteService.untagNoteToUser(noteid, userName);
					}

					if (request.getParameter("issue") != null
							&& request.getParameter("issue").equals("-1") != true) {
						String issueKey = request.getParameter("issue");
						Issue issue = getIssue(issueKey);
						noteService.tagNoteToIssue(note, issue);
					}
					// redirect to url
					if (request.getParameter("url") != null) {
						response.sendRedirect(request.getParameter("url"));
					} else {
						response.sendRedirect(request.getContextPath()
								+ "/secure/ViewProfile.jspa");
					}
				}
			} else if (action.equals("Delete")) {
				int id = Integer.parseInt(request.getParameter("id"));
				noteService.delete(id);
				// redirect to url
				if (request.getParameter("url") != null) {
					response.sendRedirect(request.getParameter("url"));
				} else {
					response.sendRedirect(request.getContextPath()
							+ "/secure/ViewProfile.jspa");
				}
				
			} else if (action.equals("Update")) {
				if (request.getParameter("id") != null) {
					int id = Integer.parseInt(request.getParameter("id"));
					Note note = null;
					// update content and priority of note
					if (request.getParameter("content") != null) {
						String content = request.getParameter("content");
						int priority = -1;
						if (request.getParameter("priority") != null) {
							priority = Integer.parseInt(request
									.getParameter("priority"));
						}
						note = noteService.update(id, content, priority);
					} else {
						note = noteService.getNote(id);
					}
					// update tagged users
					if (request.getParameter("user") != null) {
						com.atlassian.crowd.embedded.api.User[] listUsers;
						if (request.getParameter("user").equals("-1") != true) {
							String userName = request.getParameter("user");
							listUsers = new com.atlassian.crowd.embedded.api.User[] { jiraUserManager
									.getUser(userName) };
						} else {
							listUsers = new com.atlassian.crowd.embedded.api.User[] {};
						}

						noteService.associateUsers(note, listUsers);
					}
					// update tagged issues
					if (request.getParameter("issue") != null) {
						Issue[] listIssues;
						if (request.getParameter("issue").equals("-1") != true) {
							String issueKey = request.getParameter("issue");
							Issue issue = getIssue(issueKey);
							listIssues = new Issue[] { issue };
						} else {
							listIssues = new Issue[] {};
						}
						noteService.associateIssues(note, listIssues);
					}
					// redirect to url
					if (request.getParameter("url") != null) {
						response.sendRedirect(request.getParameter("url"));
					} else {
						response.sendRedirect(request.getContextPath()
								+ "/secure/ViewProfile.jspa");
					}
				}
			}
		}
	}

	private void enforceLoggedIn(HttpServletRequest req, HttpServletResponse res)
			throws IOException {
		// if (jiraUserManager.getRemoteUsername() == null) {
		// res.sendRedirect(req.getContextPath() + "/plugins/servlet/login");
		// }
	}
}
